perm filename CURVE.SAI[SYS,HE]5 blob
sn#024410 filedate 1973-02-13 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00012 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00003 00002 ENTRY CURVE1
00005 00003 ⊃ FIND A POINT ON LINE CLOSEST TO X,Y
00007 00004 ⊃ arrays and variables which control processing:
00011 00005 ⊃ MOVE POINTS NEAR CORNERS TO CLOSEST LINE
00014 00006 ⊃ MAKE A NEW LINE CONNECTING PARALLEL SEGMENTS
00016 00007 ⊃ HERE WE CURVE FIT ONE SEGMENT
00018 00008 ⊃ DISPLAY LINES FIT THROUGH ROW INDEX
00020 00009 ⊃ PASS 1, BREAK OUTLINE INTO SHORT SEGMENTS
00024 00010 ⊃ COMBINE SMALL SEGMENTS USING TOLER2
00027 00011 ⊃ COMPUTE NEW CORNERS
00032 00012 ⊃ STORE DATA IN OUTPUT ARRAY
00035 ENDMK
⊗;
ENTRY CURVE1;
BEGIN "CURVE"
REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
REQUIRE "DPYSUB.HDR[SYS,HE]" SOURCE_FILE;
REQUIRE "MISCUR[SYS,HE]" LOAD_MODULE;
REQUIRE "SQRT[SYS,HE]" LOAD_MODULE;
REQUIRE 500 STRING_SPACE;
REQUIRE "EDGLIB.REL[SYS,HE]" LIBRARY;
REQUIRE "HELIB.REL[1,3]" LIBRARY;
INTERNAL REAL TOLER,MINLEN,TOLER2,CORDIF,CORMX;
INTERNAL BOOLEAN XDEB, DD_DISP, XDMP, DISCUR;
DEFINE SAFEX="SAFE",SMAX="200",⊃="COMMENT",CRLF="'15&'12";
REAL X,Y, XX, YY;
INTEGER DEND;
INTERNAL INTEGER FRAMEX;
EXTERNAL INTEGER FRAMEY;
SAFEX INTEGER ARRAY DISPL[1:300];
FORWARD PROCEDURE CUR2(REFERENCE INTEGER SCNT;SAFEX REAL ARRAY D,ODAT;
SAFEX INTEGER ARRAY JOIN;INTEGER DSTR,S_MAX);
EXTERNAL PROCEDURE FADCHG(REAL X,Y; PROCEDURE PROC);
EXTERNAL PROCEDURE FRDCHG(REAL X,Y; PROCEDURE PROC);
EXTERNAL PROCEDURE DISP(REAL ARRAY D);
EXTERNAL REAL PROCEDURE SQRT(REAL X);
INTERNAL INTEGER PROCEDURE CUR1(SAFEX REAL ARRAY D,LINE;
SAFEX INTEGER ARRAY JOIN;REFERENCE INTEGER SCNT,S_MAX);
BEGIN INTEGER STRT;
SCNT ← 0;
STRT ← 1;
DO BEGIN
CUR2(SCNT,D,LINE,JOIN,STRT,S_MAX);
STRT ← D[STRT,2];
END UNTIL ¬STRT;
RETURN(IF SCNT<4 THEN -2 ELSE 0);
END;
⊃ FIND A POINT ON LINE CLOSEST TO X,Y;
SIMPLE PROCEDURE GETPNT(REAL X,Y,A,B,C; REFERENCE REAL XX, YY);
BEGIN
IF ABS(A)>ABS(B) THEN
BEGIN
YY ← (-A*B*X+A↑2*Y+B*C)/(A↑2+B↑2);
XX ← (C-B*Y)/A;
END ELSE BEGIN
XX ← (A*C+B↑2*X-A*B*Y)/(A↑2+B↑2);
YY ← (C-A*X)/B;
END;
END;
⊃ DRAW AN ARROW_DPY;
SIMPLE INTERNAL PROCEDURE ARROW_DPY(REAL X,Y);
BEGIN
DPYBRT(3);
FADCHG(X,Y,AIVECT);
RVECT(60,0);
RIVECT(-60,0);
RVECT(20,14);
RIVECT(0,-28);
RVECT(-20,14);
DPYBRT(7);
END;
⊃ COMPUTE COEFICIENTS OF AX+BY=C;
EXTERNAL PROCEDURE COEF(SAFEX REAL ARRAY X);
⊃ COMPUTE LEAST SQUARES ERROR OF FIT AND RETURN;
EXTERNAL REAL PROCEDURE ERROR(SAFEX REAL ARRAY X);
⊃ CALCULATE NEW CORNER POSITION. TRUE IF CORNER
EXISTS, FALSE IF LINES PARALLEL;
SIMPLE BOOLEAN PROCEDURE CORNER_CUR(SAFEX REAL ARRAY A1,A2;
REFERENCE REAL X,Y);
BEGIN REAL DENOM;
IF ABS(DENOM←A1[7]*A2[8]-A1[8]*A2[7])<.001 THEN RETURN(FALSE);
X ← (A2[8]*A1[9]-A1[8]*A2[9])/DENOM;
Y ← (A1[7]*A2[9]-A2[7]*A1[9])/DENOM;
RETURN(TRUE);
END;
⊃ arrays and variables which control processing:
D contains the raw edge points from the edge follower in the format
described under the GET_DATA command. Here, DSTR points to
the start of the current block (the first coords in DSTR+1)
and DEND points to the end of the block. In between are the
X,Y coordinate pairs.
SUMS contains the output of pass 1, one seqment per row. There are
thirteen columns per row filled as follows:
1-6 are the sums X, Y, X↑2, Y↑2, XY, and N
7-9 are the line coefficients A, B, and C
10-11 are pointers to the coords of the ends of the line
SEGS is used in pass one to indicate breaks in the segment
Each row points into D to the starting and ending
coordinates of the partial segment.
INDEX is the last used row of SUMS
SIND is the last used row of SEGS (and the one being processed)
LOOP is TRUE is the initial segment was a closed curve
LINE is the output array containing the coordinates of the lines
JOIN tells which endpoints in LINE are linked
SCNT is the maximum index of LINE
TEMP,T1,T2 hold rows of SUMS while being processed in later passes
COUT holds the computed coordinates during pass 3
;
SIMPLE INTERNAL PROCEDURE CURVON;
BEGIN INTEGER I;
OUTSTR("DISPLAY?");
IF INCHWL="Y" THEN DISCUR ← TRUE ELSE
BEGIN
RELPOG(FRAMEX);
RELPOG(FRAMEY);
END;
OUTSTR("DUMP?");
IF INCHWL="Y" THEN
BEGIN
OPEN(3,"DSK",0,0,2,100,I,I);
ENTER(3,"CURVE.DBG",I);
XDMP ← TRUE;
END;
END;
SIMPLE INTERNAL PROCEDURE CUROFF;
BEGIN
DISCUR ← XDMP ← XDEB ← FALSE;
HYDPOG(FRAMEX);
HYDPOG(FRAMEY);
RELEASE(3);
END;
⊃ MOVE POINTS NEAR CORNERS TO CLOSEST LINE;
PROCEDURE CORFIX(SAFEX REAL ARRAY F, L, D; INTEGER STR);
BEGIN SAFEX REAL ARRAY T[1:11];
BOOLEAN TOF;
INTEGER P1, P2, INC, CNT;
REAL E1, E2, X, Y, A, B, C;
P1 ← F[11];
X ← D[P1,1];
Y ← D[P1,2];
E1←ABS(((A←F[7])*X+(B←F[8])*Y-F[9])/SQRT(A↑2+B↑2));
E2←ABS(((A←L[7])*X+(B←L[8])*Y-L[9])/SQRT(A↑2+B↑2));
INC ← 1;
IF ¬(TOF←E1<E2) THEN
BEGIN ARRTRAN(T,F);ARRTRAN(F,L);ARRTRAN(L,T);INC←-1;END;
WHILE TRUE DO
BEGIN
L[1] ← L[1]-X;
L[2] ← L[2]-Y;
L[3] ← L[3]-X↑2;
L[4] ← L[4]-Y↑2;
L[5] ← L[5]-X*Y;
L[6] ← L[6]-1.0;
COEF(L);
P1 ← P1+INC;
IF P1>DEND THEN P1←STR+1 ELSE IF P1=STR THEN P1←DEND;
IF ¬L[6] THEN DONE;
X ← D[P1,1];
Y ← D[P1,2];
E1←ABS(((A←F[7])*X+(B←F[8])*Y-F[9])/SQRT(A↑2+B↑2));
E2←ABS(((A←L[7])*X+(B←L[8])*Y-L[9])/SQRT(A↑2+B↑2));
IF E1>E2 THEN DONE;
IF E1<1.0 THEN
BEGIN "ADDON"
F[1] ← F[1]+X;
F[2] ← F[2]+Y;
F[3] ← F[3]+X↑2;
F[4] ← F[4]+Y↑2;
F[5] ← F[5]+X*Y;
F[6] ← F[6]+1.0;
COEF(F);
END "ADDON";
END;
IF ¬TOF THEN BEGIN ARRTRAN(T,F);ARRTRAN(F,L);ARRTRAN(L,T);END;
P2 ← P1-INC;
IF P2>DEND THEN P2←STR+1 ELSE IF P2=STR THEN P2←DEND;
F[11] ← IF TOF THEN P2 ELSE P1;
L[10] ← IF TOF THEN P1 ELSE P2;
IF F[6]≤1.0 THEN F[6] ←0.0;
IF L[6]≤1.0 THEN L[6] ←0.0;
RETURN;
END;
⊃ MAKE A NEW LINE CONNECTING PARALLEL SEGMENTS;
BOOLEAN PROCEDURE MAKLIN(SAFEX REAL ARRAY A,B,C,D; INTEGER STR);
BEGIN INTEGER P1, P2, P3, P4;
REAL X, Y, XQ, YQ, XY, N;
SIMPLE BOOLEAN PROCEDURE PROC(INTEGER P;REAL ARRAY Z,Q);
BEGIN REAL AA, BB, E, XX, YY;
XX ← Q[P,1];
YY ← Q[P,2];
E←ABS(((AA←Z[7])*XX+(BB←Z[8])*YY-Z[9])/SQRT(AA↑2+BB↑2));
IF E<1.0 THEN RETURN(TRUE);
X ← X+XX;
Y ← Y+YY;
XQ ← XQ+XX↑2;
YQ ← YQ+YY↑2;
XY ← XY+XX*YY;
N ← N+1.0;
Z[1] ← Z[1] -XX;
Z[2] ← Z[2] -YY;
Z[3] ← Z[3] -XX↑2;
Z[4] ← Z[4] -YY↑2;
Z[5] ← Z[5] -YY*XX;
IF (Z[6]←Z[6]-1.0)≤0 THEN RETURN(TRUE);
COEF(Z);
RETURN(FALSE);
END;
X ← Y ← XQ ← YQ ← XY ← N ← 0;
P1 ← A[11]; P2 ← B[10]; P3 ← A[10]; P4 ← B[11];
DO BEGIN "SUM1"
IF PROC(P1,A,D) THEN DONE;
IF (P1←P1-1)≤STR THEN P1←DEND;
END "SUM1" UNTIL P1=P3;
DO BEGIN "SUM2"
IF PROC(P2,B,D) THEN DONE;
IF (P2←P2+1)>DEND THEN P2←STR+1;
END "SUM2" UNTIL P2=P4;
IF N<1.5 THEN RETURN(FALSE);
C[1] ← X;
C[2] ← Y;
C[3] ← XQ;
C[4] ← YQ;
C[5] ← XY;
C[6] ← N;
COEF(C);
A[11] ← P1;
B[10] ← P2;
C[10] ← IF (P1+1)>DEND THEN STR+1 ELSE P1+1;
C[11] ← IF (P2-1)≤STR THEN DEND ELSE P2-1;
RETURN(TRUE);
END;
⊃ HERE WE CURVE FIT ONE SEGMENT;
PROCEDURE CUR2(REFERENCE INTEGER SCNT;SAFEX REAL ARRAY D, LINE;
SAFEX INTEGER ARRAY JOIN;INTEGER DSTR,S_MAX);
BEGIN BOOLEAN LOOP, COMB, HALT;
REAL EX, EY, E1, E2, EPS, LERR, AX, AY, X1, Y1;
SAFEX REAL ARRAY SUMS[1:SMAX,1:11], TEMP,T1,T2,T3[1:11];
SAFEX INTEGER ARRAY SEGS[1:SMAX,1:2];
INTEGER INDEX, I, J, K, DPNT, SIND, PT1, PT2, L;
LABEL L1, L2, L3, L4, L5, L6, L7, L8, L9, L10, L13;
⊃ RETURN INDEX FOR COORDS FURTHEST FROM THE LINE THROUGH
THE ENDPOINTS;
INTEGER PROCEDURE GETMAX(INTEGER S,E);
BEGIN REAL A,B,C,X1,X2,Y1,Y2,DENOM,M,T;
EXTERNAL INTEGER PROCEDURE LOOP1(REAL ARRAY D;
REAL A,B,C,DENOM;INTEGER I,DSTR,DEND,E);
INTEGER I,J,K;
X1 ← D[S,1];
Y1 ← D[S,2];
X2 ← D[E,1];
Y2 ← D[E,2];
A ← Y1-Y2;
B ← X2-X1;
C ← X1*Y2-X2*Y1;
DENOM ← SQRT(A↑2+B↑2);
I ← S-1;
J ← LOOP1(D,A,B,C,DENOM,I,DSTR,DEND,E);
IF ¬J THEN USERERR(0,0,"GETMAX LOST BIG"&CRLF);
RETURN(J);
END;
⊃ DISPLAY LINES FIT THROUGH ROW INDEX;
PROCEDURE DEBDIS(REAL TOLER,EPS; INTEGER INDEX, PAS);
BEGIN INTEGER I, J, K;
REAL X, Y, A, B, C;
IF DD_DISP THEN
BEGIN
RELPOG(FRAMEX);
IF PAS=1 THEN DISP(D);
END;
IF FRAMEX<0 THEN FRAMEX ← GETPOG;
DPYSET(DISPL);
DPYBRT(7);
DPYBIG(3);
FADCHG(10.0,240.0,AIVECT);
SETFORMAT(0,0);
DPYSST("PASS "&CVS(PAS));
SETFORMAT(7,4);
DPYSST(" TOLER="&CVF(TOLER)&" EPS="&CVF(EPS));
FADCHG(0,0,AIVECT);
FOR I←1 STEP 1 UNTIL INDEX DO
BEGIN
J ← SUMS[I,10];
K ← SUMS[I,11];
A ← SUMS[I,7];
B ← SUMS[I,8];
C ← SUMS[I,9];
GETPNT(D[J,1],D[J,2],A,B,C,X,Y);
FRDCHG(X,Y,RIVECT);
GETPNT(D[K,1],D[K,2],A,B,C,X,Y);
FRDCHG(X,Y,RVECT);
END;
END;
⊃ PASS 1, BREAK OUTLINE INTO SHORT SEGMENTS;
IF DISCUR THEN
BEGIN
OUTSTR("DEBUG PASS 1?"&CRLF);
XDEB ← INCHWL="Y";
END;
INDEX ← 0;
DEND ← DSTR+(I←D[DSTR,1]);
LOOP ← D[DSTR,4];
IF (LOOP∧I<6)∨(¬LOOP∧I<3) THEN GO TO L2;
IF LOOP THEN
BEGIN "LOOP"
PT1 ← DSTR+1;
PT2 ← (DSTR+DEND) DIV 2;
SEGS[2,2] ← SEGS[1,1] ← GETMAX(PT1,PT2);
SEGS[2,1] ← SEGS[1,2] ← GETMAX(PT2, PT1);
SIND ← 2;
END "LOOP" ELSE BEGIN "NO"
SEGS[SIND←1,1] ← DSTR+1;
SEGS[SIND,2] ← DEND;
END "NO";
L1: DO BEGIN "MAIN"
EXTERNAL PROCEDURE LOOP2(REAL ARRAY TEMP,D;
INTEGER I,PT2,DEND,DSTR);
PT1 ← SEGS[SIND,1];
PT2 ← SEGS[SIND,2];
I ← PT1-1;
LOOP2(TEMP,D,I,PT2,DEND,DSTR);
EPS ← ABS(ERROR(TEMP))/TEMP[6];
IF XDEB THEN
BEGIN "D1"
DEBDIS(TOLER,EPS,INDEX,1);
FOR J←SIND STEP -1 UNTIL 1 DO
BEGIN REAL A,B,C,E;
I ← SEGS[J,1];
K ← SEGS[J,2];
A ← D[I,1];
B ← D[I,2];
IF J=SIND∨A≠C∨B≠E THEN FRDCHG(A,B,RIVECT);
C ← D[K,1];
E ← D[K,2];
FRDCHG(C,E,RVECT);
END;
ARROW_DPY(D[PT1,1], D[PT1,2]);
ARROW_DPY(D[PT2,1], D[PT2,2]);
DPYOUT(FRAMEX);
INCHWL;
END "D1";
IF EPS>TOLER THEN
BEGIN "BREAK"
IF (SIND←SIND+1)>SMAX THEN
USERERR(0,0,"SEGS OVERFLOWED"&CRLF);
SEGS[SIND,1] ← PT1;
SEGS[SIND-1,1]←SEGS[SIND,2]←GETMAX(PT1,PT2);
GO TO L1;
END "BREAK";
IF (INDEX←INDEX+1)>SMAX THEN
USERERR(0,0,"SUM ARRAY OVERFLOW"&CRLF);
TEMP[10] ← PT1;
TEMP[11] ← PT2;
L13: IF INDEX>1 THEN
BEGIN "SAVE"
ARRBLT(T1[1],SUMS[INDEX-1,1],11);
CORFIX(T1,TEMP,D,DSTR);
IF T1[6] THEN ARRBLT(SUMS[INDEX-1,1],T1[1],11)
ELSE INDEX←INDEX-1;
END "SAVE";
IF TEMP[6] THEN ARRBLT(SUMS[INDEX,1],TEMP[1],11)
ELSE INDEX←INDEX-1;
END "MAIN" UNTIL ¬(SIND ← SIND-1);
IF INDEX>1∧LOOP THEN
BEGIN "FINISH"
ARRBLT(T1[1],SUMS[1,1],11);
ARRBLT(T2[1],SUMS[INDEX,1],11);
CORFIX(T2,T1,D,DSTR);
I←INDEX;
IF T1[6] THEN ARRBLT(SUMS[1,1],T1[1],11) ELSE
BEGIN
I←1;
INDEX←INDEX-1;
END;
IF T2[6] THEN ARRBLT(SUMS[I,1],T2[1],11) ELSE INDEX←INDEX-1;
END "FINISH";
⊃ COMBINE SMALL SEGMENTS USING TOLER2;
L2: IF DISCUR THEN
BEGIN
OUTSTR("DEBUG PASS 2?"&CRLF);
XDEB←INCHWL="Y";
RELPOG(FRAMEY);
END;
L8: COMB ← FALSE;
I←1;
IF INDEX≤2 THEN GO TO L10;
HALT ← FALSE;
L5: J ← I;
ARRBLT(T1[1],SUMS[I,1],11);
L7: IF J=1∧HALT THEN GO TO L3;
IF (I←I+1)>INDEX THEN
BEGIN HALT←TRUE;
IF LOOP THEN I←1 ELSE GO TO L3;
END;
ARRBLT(T2[1],SUMS[I,1],11);
L6: FOR K←1 STEP 1 UNTIL 6 DO TEMP[K]←T1[K]+T2[K];
TEMP[10]←T1[10];
TEMP[11]←T2[11];
IF (I←I+1)>INDEX THEN
BEGIN
HALT ← TRUE;
IF LOOP THEN I←1 ELSE GO TO L4;
END;
ARRBLT(T3[1],SUMS[I,1],11);
FOR K←1 STEP 1 UNTIL 6 DO T1[K]←T2[K]+T3[K];
T1[10] ← T2[10];
T1[11]←T3[11];
L4: E1 ← ABS(ERROR(TEMP))/TEMP[6];
E2 ← ABS(ERROR(T1))/T1[6];
IF XDEB THEN
BEGIN
DEBDIS(TOLER2,E1,INDEX,2);
FADCHG(250.0,240.0,AIVECT);
DPYSST("EPS2= "&CVF(E2));
ARROW_DPY(D[TEMP[10],1],D[TEMP[10],2]);
IF HALT∧¬LOOP THEN
ARROW_DPY(D[TEMP[11],1],D[TEMP[11],2]) ELSE
ARROW_DPY(D[T1[11],1],D[T1[11],2]);
DPYOUT(FRAMEX);
INCHWL;
END;
IF E1<TOLER2∧((HALT∧¬LOOP)∨E2>E1) THEN
BEGIN
IF ¬HALT∧LOOP∧J=1 THEN GO TO L9;
COMB ← TRUE;
IF J<INDEX THEN
BEGIN
ARRBLT(SUMS[J,1],TEMP[1],11);
IF J+1<INDEX THEN ARRBLT(SUMS[J+1,1],SUMS[J+2,1],
(INDEX-J-1)*11);
END ELSE BEGIN
ARRBLT(SUMS[1,1],TEMP[1],11);
J ← 1;
END;
IF (INDEX ← INDEX-1)<I THEN I←1;
IF HALT∧¬LOOP THEN GO TO L3;
ARRTRAN(T1,TEMP);
I ← J;
GO TO L7;
END;
IF ¬HALT∨LOOP THEN IF E2<TOLER2 THEN
BEGIN
ARRTRAN(T1,T2);
ARRTRAN(T2,T3);
IF (J←J+1)>INDEX THEN J←1;
GO TO L6;
END ELSE BEGIN
L9: ARRTRAN(T1,T3);
J←I;
IF ¬HALT∨J>2 THEN GO TO L7;
END;
L3: IF COMB THEN GO TO L8;
⊃ COMPUTE NEW CORNERS
AND DELETE EXTRA SEGMENTS;
L10: IF DISCUR THEN
BEGIN
OUTSTR("DEBUG PASS 3?"&CRLF);
XDEB ← INCHWL="Y";
END;
IF INDEX<1∨(LOOP∧INDEX<3) THEN RETURN;
FOR I←1 STEP 1 UNTIL INDEX DO
IF SUMS[I,6]<MINLEN ∧(LOOP∨(I≠1∧I≠INDEX)) THEN
BEGIN "SHORT"
ARRBLT(TEMP[1],SUMS[IF I-1>0 THEN I-1 ELSE INDEX,1],11);
ARRBLT(T1[1],SUMS[IF I+1>INDEX THEN 1 ELSE I+1,1],11);
J ← SUMS[I,10];
K ← SUMS[I,11];
AX ← (D[J,1]+D[K,1])/2;
AY ← (D[J,2]+D[K,2])/2;
IF CORNER_CUR(TEMP,T1,X,Y)∨(E1←((X-AX)↑2+(Y-AY)↑2)<CORDIF)
THEN BEGIN "DELETE"
ARRBLT(SUMS[I,1],SUMS[I+1,1],(INDEX-I)*11);
INDEX ← INDEX-1;
IF XDEB THEN
BEGIN "D2"
DEBDIS(CORDIF,E1,INDEX,3);
FADCHG(250.0,240.0,AIVECT);
DPYSST("DELETED");
ARROW_DPY(X,Y);
DPYOUT(FRAMEX);
INCHWL;
END "D2";
END "DELETE";
END "SHORT";
IF INDEX<1∨(LOOP∧INDEX<3) THEN RETURN;
BEGIN "COMPUT" SAFEX REAL ARRAY COUT[1:INDEX+10,1:2];
LABEL L12, L9;
L ← 1;
IF ¬LOOP THEN
BEGIN "NOLOP"
GETPNT(D[SUMS[1,10],1],D[SUMS[1,10],2],SUMS[1,7],
SUMS[1,8],SUMS[1,9],COUT[1,1],COUT[1,2]);
L ← L+1;
GETPNT(D[SUMS[INDEX,11],1],D[SUMS[INDEX,11],2],
SUMS[INDEX,7],SUMS[INDEX,8],SUMS[INDEX,9],
XX,YY);
END "NOLOP";
IF INDEX=1 THEN IF SUMS[1,6]<4 THEN RETURN ELSE GO TO L9;
FOR I←1 STEP 1 UNTIL INDEX-1 DO
BEGIN "CORNER"
J←I+1;
L12: ARRBLT(T1[1],SUMS[I,1],11);
ARRBLT(T2[1],SUMS[J,1],11);
IF CORNER_CUR(T1,T2,X,Y) THEN
BEGIN "FIND"
PT1 ← T2[10];
PT2 ← T1[11];
EX ← D[PT1,1];
EY ← D[PT1,2];
AX ← D[PT2,1];
AY ← D[PT2,2];
E1←(EX-AX)↑2+(EY-AY)↑2;
IF E1>CORDIF THEN
OUTSTR("BAD CORNER MATCH"&CRLF);
E2 ← IF E1<2.0 THEN (AX-X)↑2+(AY-Y)↑2 ELSE
(X-(AX+EX)/2)↑2+(Y-(AY+EY)/2)↑2;
IF E2<CORDIF THEN
BEGIN "GOOD"
COUT[L,1] ← X;
COUT[L,2] ← Y;
END "GOOD" ELSE BEGIN "BAD"
OUTSTR("BAD CORNER REJECTED"&
CVF(E2)&'15&'12);
IF E2>CORMX∧
MAKLIN(T1,T2,TEMP,D,DSTR)∧
CORNER_CUR(T1,TEMP,AX,AY)∧
CORNER_CUR(TEMP,T2,EX,EY)
THEN BEGIN "ADLINE"
COUT[L,1] ← AX;
COUT[L,2] ← AY;
L ← L+1;
COUT[L,1] ← EX;
COUT[L,2] ← EY;
END "ADLINE" ELSE BEGIN
COUT[L,1] ← (EX+AX)/2;
COUT[L,2] ← (EY+AY)/2;
END;
END "BAD";
L ← L+1;
END "FIND" ELSE BEGIN "NOF"
FOR K←1 STEP 1 UNTIL 6 DO T1[K]←T1[K]+T2[K];
T1[11] ← T2[11];
COEF(T1);
ARRBLT(SUMS[IF J=1 THEN J ELSE I,1],
T1[1],11);
ARRBLT(SUMS[I,1],SUMS[I+1,1],(INDEX-I)*11);
INDEX ← INDEX-1;
END "NOF";
END "CORNER";
IF INDEX=1 THEN GO TO L9;
IF LOOP∧J>1 THEN BEGIN J←1;I←INDEX;GO TO L12;END;
INDEX ← L-1;
L9: IF INDEX<1∨(LOOP∧INDEX<3) THEN RETURN;
⊃ STORE DATA IN OUTPUT ARRAY;
IF SCNT+INDEX+1>S_MAX THEN OUTSTR("ODAT OVERFLOW"&CRLF) ELSE
BEGIN
FOR I ← 1 STEP 1 UNTIL INDEX-1 DO
BEGIN
LINE[SCNT←SCNT+1,1] ← COUT[I,1];
LINE[SCNT,2] ← COUT[I,2];
LINE[SCNT,3] ← COUT[I+1,1];
LINE[SCNT,4] ← COUT[I+1,2];
JOIN[SCNT,1] ← I≠1∨LOOP;
JOIN[SCNT,2] ← TRUE;
END;
LINE[SCNT←SCNT+1,1]←COUT[INDEX,1];
LINE[SCNT,2]←COUT[INDEX,2];
JOIN[SCNT,1]←TRUE;
IF LOOP THEN
BEGIN
LINE[SCNT,3]←COUT[1,1];
LINE[SCNT,4]←COUT[1,2];
JOIN[SCNT,2]←TRUE;
END ELSE BEGIN
LINE[SCNT,3]←XX;
LINE[SCNT,4]←YY;
JOIN[SCNT,2]←FALSE;
END;
END;
END "COMPUT";
END;
END;